import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken, setToken } from '@/utils/auth'
import router from '@/router'
// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
})

//是否处在刷新token的状态下
var isRefreshingToken = false
//用于缓存之前的请求
var requestCache = []


// request interceptor
service.interceptors.request.use(
  request => {
    // do something before request is sent

    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      //会在后边手动赋值,如果手动赋值了那就不再自动赋值

      request.headers['authenticator'] = getToken()

    }
    return request
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)



// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {

    let { config } = response;

    const res = response.data
    //状态处于token过期时
    if (res.code === 40001) {
      if (!isRefreshingToken) {
        if (router.currentRoute.name !== 'login') {
          isRefreshingToken = true;//正在刷新中
          console.log("发送刷新token请求")
          service({
            url: "/user/token",
            method: "post",
            headers: { 'Content-Type': 'application/json;charset=UTF-8' },
            data: JSON.stringify({ token: getToken() })
          })
            .then(res => {
              var token = res
              //修改内部token数据
              store.dispatch("user/resetToken")
                .then(() => {
                  store.commit("user/SET_TOKEN", token);
                  setToken(token)
                  isRefreshingToken = false;//退出刷新状态
                  console.log("需要重发:" + requestCache.length + "个请求")
                  requestCache.forEach(req => req())
                  requestCache = []
                })
            })
            .catch(err => {
              console.error(err);
            })
        }
        //同样的,这个请求也应该被缓存
        console.log("缓存:" + config + "请求")
        return new Promise((resolve) => {
          requestCache.push(() => {
            //去掉开头的"/api"
            config.url = config.url.substring(4)
            service(config).then(res => { resolve(res) })
          })
        })
      } else {
        //缓存中存放一个 func(token)的函数
        //调用即可重放请求,使用config,即上边从response中取出的对象
        //config看上去是保存了请求的配置的
        console.log("缓存:" + config + "请求")
        return new Promise((resolve) => {
          requestCache.push(() => {
            //去掉开头的"/api"
            config.url = config.url.substring(4)
            service(config).then(res => { resolve(res) })
          })
        })
      }
    }



    // if the custom code is not 20000, it is judged as an error.
    if (res.code === 400 || res.code === 404) {
      Message({
        message: res.msg,
        type: 'error',
        duration: 5 * 1000
      })
      return Promise.reject(res.code)
    }
    // 50001:没有token或者token错误; 50002: Other clients logged in; 50003: Token expired;
    if (res.code === 50001 || res.code === 50002 || res.code === 50003) {
      // to re-login
      let msg = ""
      if (res.code === 50001) {
        msg = "您未登录,请重新登录"
      } else if (res.code === 5002) {
        msg = "您的账号已在别处登录"
      } else if (res.code === 5003) {
        msg = "长时间未登录,您已经下线"
      }
     
      if (store.getters.logged) {
        MessageBox.confirm(msg, '确认退出', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            router.replace("/")
          })
        })
      }
      store.commit("user/SET_LOGGED",false)
      return Promise.reject(res.code)
    } else {
      if (res.code === 200) {
        //此处直接取出数据
        return res.data
      } else {
        return res
      }
    }
  },
  error => {
    console.log('err' + error) // for debug
    return Promise.reject(error)
  }
)

export default service
